import * as Cesium from 'cesium/Cesium'
import MeasurementSettings from "./MeasurementSettings";
import PolylinePrimitive from "./PolylinePrimitive";
import Measurement from "./Measurement";
import MeasureUnits from "./MeasureUnits";
import getWorldPosition from "./getWorldPosition";

function getIcon(e) {
    return '<svg viewBox="0 0 30 30" height="' + e + 'px" width="' + e + 'px">\n                 <g transform="translate(0,-267)">\n                  <path d="m 4.934989,292.6549 20.67981,-20.80395"/>\n                   <circle r="2.0788691" cy="270.1637" cx="27.025297"/>\n                   <circle r="2.0788691" cy="294.07068" cx="3.1183045"/>\n                 </g>\n               </svg>\n'
}
function getComponentIcon(e) {
    return '<svg viewBox="0 0 30 30" height="' + e + 'px" width="' + e + 'px">\n                 <g transform="translate(0,-267)">\n                   <path d="m 4.934989,292.6549 20.67981,-20.80395" />\n                   <circle r="2.0788691" cy="270.1637" cx="27.025297" />\n                   <circle r="2.0788691" cy="294.07068" cx="3.1183045" />\n                   <path style="stroke-dasharray:2.00314951, 1.00157475;stroke-dashoffset:0;" d="m 3.3194019,292.73274 -0.046996,-22.53109 21.6420984,-0.0266" />\n                 </g>\n               </svg>\n'
}

var Mode = {
    BeforeDraw: 0,
    Drawing: 1,
    AfterDraw: 2
},cart2Scratch1$1 = new Cesium.Cartesian2
    , cart2Scratch2$1 = new Cesium.Cartesian2
    , scratchCarto$2 = new Cesium.Cartographic
    , cart3Scratch1$3 = new Cesium.Cartesian3
    , cart3Scratch2$2 = new Cesium.Cartesian3
    , cart3Scratch3$1 = new Cesium.Cartesian3;

function DistanceMeasurement(e) {
    e = Cesium.defaultValue(e, Cesium.defaultValue.EMPTY_OBJECT),
        Measurement.call(this, e);
    var t = this
        , i = this._pointCollection
        , r = this._labelCollection
        , n = this._primitives
        , a = this._scene
        , o = [new Cesium.Cartesian3, new Cesium.Cartesian3]
        , s = [new Cesium.Cartesian3, new Cesium.Cartesian3, new Cesium.Cartesian3]
        , l = [new Cesium.Cartesian3, new Cesium.Cartesian3, new Cesium.Cartesian3]
        , c = new Cesium.Cartesian2(-9,0)
        , u = new Cesium.Cartesian2(9,0)
        , d = a.frameState.mapProjection.ellipsoid;
    this._startPoint = i.add(MeasurementSettings.getPointOptions()),
        this._endPoint = i.add(MeasurementSettings.getPointOptions()),
        this._positions = o,
        this._polyline = n.add(new PolylinePrimitive(MeasurementSettings.getPolylineOptions({
            ellipsoid: d,
            width: 3,
            show: !1,
            positions: o
        }))),
        this._xyPolylinePositions = s,
        this._xyPolyline = n.add(new PolylinePrimitive(MeasurementSettings.getPolylineOptions({
            ellipsoid: d,
            width: 2,
            positions: s,
            materialType: Cesium.Material.PolylineDashType
        }))),
        this._xyBoxPositions = l,
        this._xyBox = n.add(new PolylinePrimitive(MeasurementSettings.getPolylineOptions({
            ellipsoid: d,
            width: 1,
            positions: l
        }))),
        this._label = r.add(MeasurementSettings.getLabelOptions({
            horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
            verticalOrigin: Cesium.VerticalOrigin.TOP,
            pixelOffset: new Cesium.Cartesian2(10,10)
        })),
        this._xPixelOffset = u,
        this._xLabel = r.add(MeasurementSettings.getLabelOptions()),
        this._xAngleLabel = r.add(MeasurementSettings.getLabelOptions({
            horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
            verticalOrigin: Cesium.VerticalOrigin.MIDDLE,
            pixelOffset: u
        })),
        this._yPixelOffset = c,
        this._yLabel = r.add(MeasurementSettings.getLabelOptions({
            horizontalOrigin: Cesium.HorizontalOrigin.RIGHT,
            pixelOffset: c
        })),
        this._yAngleLabel = r.add(MeasurementSettings.getLabelOptions({
            verticalOrigin: Cesium.VerticalOrigin.TOP,
            pixelOffset: new Cesium.Cartesian2(0,9)
        })),
        this._distance = 0,
        this._xDistance = 0,
        this._yDistance = 0,
        this._xAngle = 0,
        this._yAngle = 0,
        this._mode = Mode.BeforeDraw,
        this._showComponentLines = Cesium.defaultValue(e.showComponentLines, !1),
        this._removeEvent = a.preRender.addEventListener(function() {
            t._updateLabelPosition()
        })
}
DistanceMeasurement.prototype = Object.create(Measurement.prototype),
    DistanceMeasurement.prototype.constructor = DistanceMeasurement,
    Cesium.defineProperties(DistanceMeasurement.prototype, {
        distance: {
            get: function() {
                return this._distance
            }
        },
        horizontalDistance: {
            get: function() {
                return this._xDistance
            }
        },
        verticalDistance: {
            get: function() {
                return this._yDistance
            }
        },
        angleFromHorizontal: {
            get: function() {
                return this._xAngle
            }
        },
        angleFromVertical: {
            get: function() {
                return this._yAngle
            }
        },
        icon: {
            get: function() {
                return this._showComponentLines ? getComponentIcon(15) : getIcon(15)
            }
        },
        thumbnail: {
            get: function() {
                return this._showComponentLines ? getComponentIcon(25) : getIcon(25)
            }
        },
        type: {
            get: function() {
                return this._showComponentLines ? "组件距离" : "距离"
            }
        },
        instructions: {
            value: ["单击点云或地球以设置起点和终点", "若要进行新测量，请单击以清除以前的测量"]
        },
        id: {
            get: function() {
                return this._showComponentLines ? "componentDistanceMeasurement" : "distanceMeasurement"
            }
        },
        showComponentLines: {
            get: function() {
                return this._showComponentLines
            },
            set: function(e) {
                this._showComponentLines = e,
                this._mode !== Mode.BeforeDraw && this._updateComponents()
            }
        }
    }),
    DistanceMeasurement.prototype._updateComponents = function() {
        var e = this._showComponentLines
            , t = this._xLabel
            , i = this._yLabel
            , r = this._xAngleLabel
            , n = this._yAngleLabel
            , a = this._xyPolyline
            , o = this._xyBox;
        if (t.show = !1,
            i.show = !1,
            r.show = !1,
            n.show = !1,
            a.show = !1,
            o.show = !1,
            e) {
            var s, l, c, u, d = this._scene.frameState.mapProjection.ellipsoid, h = this._positions,
                p = h[0], m = h[1], f = d.cartesianToCartographic(p, scratchCarto$2).height,
                g = d.cartesianToCartographic(m, scratchCarto$2).height;
            u = f < g ? (s = p,
                l = m,
                c = g,
                f) : (s = m,
                l = p,
                c = f,
                g);
            var _ = this._xyPolylinePositions;
            _[0] = Cesium.Cartesian3.clone(s, _[0]),
                _[2] = Cesium.Cartesian3.clone(l, _[2]);
            var v = d.geodeticSurfaceNormal(s, cart3Scratch1$3);
            v = Cesium.Cartesian3.multiplyByScalar(v, c - u, v);
            var y = Cesium.Cartesian3.add(s, v, _[1]);
            if (a.positions = _,
            !Cesium.Cartesian3.equalsEpsilon(y, l, Cesium.Math.EPSILON10)
            && !Cesium.Cartesian3.equalsEpsilon(y, s, Cesium.Math.EPSILON10)) {
                i.show = !0,
                    t.show = !0,
                    n.show = !0,
                    r.show = !0,
                    a.show = !0,
                    o.show = !0;
                var C = Cesium.Cartesian3.subtract(l, y, cart3Scratch1$3)
                    , S = Cesium.Cartesian3.subtract(s, y, cart3Scratch2$2)
                    , T = Math.min(Cesium.Cartesian3.magnitude(C), Cesium.Cartesian3.magnitude(S))
                    , x = 15 < T ? .15 * T : .25 * T;
                C = Cesium.Cartesian3.normalize(C, C),
                    S = Cesium.Cartesian3.normalize(S, S),
                    C = Cesium.Cartesian3.multiplyByScalar(C, x, C),
                    S = Cesium.Cartesian3.multiplyByScalar(S, x, S);
                var E = this._xyBoxPositions;
                E[0] = Cesium.Cartesian3.add(y, C, E[0]),
                    E[1] = Cesium.Cartesian3.add(E[0], S, E[1]),
                    E[2] = Cesium.Cartesian3.add(y, S, E[2]),
                    o.positions = E,
                    t.position = Cesium.Cartesian3.midpoint(y, l, cart3Scratch1$3),
                    i.position = Cesium.Cartesian3.midpoint(s, y, cart3Scratch1$3),
                    r.position = Cesium.Cartesian3.clone(l, cart3Scratch1$3),
                    n.position = Cesium.Cartesian3.clone(s, cart3Scratch1$3);
                var b = Cesium.Cartesian3.subtract(y, l, cart3Scratch2$2)
                    , P = Cesium.Cartesian3.subtract(y, s, cart3Scratch1$3)
                    , A = Cesium.Cartesian3.subtract(l, s, cart3Scratch3$1)
                    , w = Cesium.Cartesian3.angleBetween(P, A);
                A = Cesium.Cartesian3.negate(A, A);
                var D = Cesium.Cartesian3.angleBetween(b, A)
                    , M = Cesium.Cartesian3.magnitude(b)
                    , I = Cesium.Cartesian3.magnitude(P)
                    , O = this._selectedUnits
                    , R = this._selectedLocale;
                t.text = MeasureUnits.distanceToString(M, O.distanceUnits, R),
                    i.text = MeasureUnits.distanceToString(I, O.distanceUnits, R),
                    r.text = MeasureUnits.angleToString(D, O.slopeUnits, R),
                    n.text = MeasureUnits.angleToString(w, O.slopeUnits, R),
                    this._xDistance = M,
                    this._yDistance = I,
                    this._xAngle = D,
                    this._yAngle = w
            }
        }
    }
    ,
    DistanceMeasurement.prototype._updateLabelPosition = function() {
        var e = this._positions;
        if (this._mode !== Mode.BeforeDraw) {
            var t = this._scene
                , i = e[0]
                , r = e[1]
                , n = Cesium.SceneTransforms.wgs84ToWindowCoordinates(t, i, cart2Scratch1$1)
                , a = Cesium.SceneTransforms.wgs84ToWindowCoordinates(t, r, cart2Scratch2$1);
            if (Cesium.defined(n) && Cesium.defined(a)) {
                var o = this._label
                    , s = this._yLabel
                    , l = this._xAngleLabel;
                0 < (n.y - a.y) / (a.x - n.x) ? (this._yPixelOffset.x = -9,
                    this._xPixelOffset.x = 12,
                    s.pixelOffset = this._yPixelOffset,
                    s.horizontalOrigin = Cesium.HorizontalOrigin.RIGHT,
                    l.pixelOffset = this._xPixelOffset,
                    l.horizontalOrigin = Cesium.HorizontalOrigin.LEFT,
                    o.horizontalOrigin = Cesium.HorizontalOrigin.LEFT) : (this._yPixelOffset.x = 9,
                    this._xPixelOffset.x = -12,
                    s.pixelOffset = this._yPixelOffset,
                    s.horizontalOrigin = Cesium.HorizontalOrigin.LEFT,
                    l.pixelOffset = this._xPixelOffset,
                    l.horizontalOrigin = Cesium.HorizontalOrigin.RIGHT,
                    o.horizontalOrigin = Cesium.HorizontalOrigin.RIGHT)
            }
        }
    }
    ,
    DistanceMeasurement.prototype.handleClick = function(e) {
        var t = this._scene;
        this._mode === Mode.AfterDraw && this.reset();
        var i = this._mode
            , r = this._positions;
        if (i === Mode.BeforeDraw) {
            var n = DistanceMeasurement._getWorldPosition(t, e, r[0]);
            if (!Cesium.defined(n))
                return;
            this._polyline.show = !0,
                r[0] = n.clone(r[0]),
                r[1] = n.clone(r[1]),
                this._startPoint.position = n,
                this._startPoint.show = !0,
                this._mode = Mode.Drawing,
                this._polyline.positions = r
        } else
            i === Mode.Drawing && (this._endPoint.position = r[1],
                this._endPoint.show = !0,
                this._polyline.positions = r,
                this._mode = Mode.AfterDraw)
    }
    ,
    DistanceMeasurement.prototype.handleMouseMove = function(e) {
        if (this._mode === Mode.Drawing) {
            var t = this._scene
                , i = this._positions
                , r = DistanceMeasurement._getWorldPosition(t, e, cart3Scratch1$3);
            if (Cesium.defined(r)) {
                var n = i[0]
                    , a = Cesium.Cartesian3.clone(r, i[1])
                    , o = Cesium.Cartesian3.subtract(a, n, cart3Scratch1$3)
                    , s = Cesium.Cartesian3.magnitude(o)
                    , l = this._label;
                l.position = Cesium.Cartesian3.midpoint(n, a, cart3Scratch1$3),
                    l.text = MeasureUnits.distanceToString(s, this._selectedUnits.distanceUnits, this._selectedLocale),
                    l.show = !0,
                    this._distance = s,
                    this._polyline.positions = i,
                    this._updateComponents()
            }
        }
    }
    ,
    DistanceMeasurement.prototype.reset = function() {
        this._polyline.show = !1,
            this._xyPolyline.show = !1,
            this._xyBox.show = !1,
            this._label.show = !1,
            this._xLabel.show = !1,
            this._yLabel.show = !1,
            this._xAngleLabel.show = !1,
            this._yAngleLabel.show = !1,
            this._startPoint.show = !1,
            this._endPoint.show = !1,
            this._mode = Mode.BeforeDraw,
            this._distance = 0,
            this._xDistance = 0,
            this._yDistance = 0,
            this._xAngle = 0,
            this._yAngle = 0
    }
    ,
    DistanceMeasurement.prototype.isDestroyed = function() {
        return !1
    }
    ,
    DistanceMeasurement.prototype.destroy = function() {
        this._removeEvent();
        var e = this._primitives;
        e.remove(this._polyline),
            e.remove(this._xyPolyline),
            e.remove(this._xyBox);
        var t = this._pointCollection;
        t.remove(this._startPoint),
            t.remove(this._endPoint);
        var i = this._labelCollection;
        return i.remove(this._label),
            i.remove(this._xLabel),
            i.remove(this._yLabel),
            i.remove(this._xAngleLabel),
            i.remove(this._yAngleLabel),
            Cesium.destroyObject(this)
    }
    ,
    DistanceMeasurement._getWorldPosition = getWorldPosition;

export default DistanceMeasurement;
  